package com.hzw.core.collection

/**
 * 随机访问：普通for的效率高于foreach(Iterator)
 * 顺序访问：foreach(Iterator)效率高于普通for
 */

/**
 * 使用索引而不是像forEach那样的Iterator迭代接收方List。
 * 使用此功能可保存Iterator分配，这对于不可变列表或仅限于单个线程（如UI线程仅使用）的用法很有用。
 * 但是，此方法将不会检测到并发修改，除非列表的大小会因此在迭代中更改，否则可能导致无法预测的行为
 */
inline fun <T> List<T>.forEachByIndex(action: (T) -> Unit) {
    val initialSize = size
    for (i in 0..lastIndex) {
        if (size != initialSize) throw ConcurrentModificationException()
        action(get(i))
    }
}

/**
 * 使用索引而不是像forEachIndexed这样的Iterator迭代接收方List 。
 * 使用此功能可保存Iterator分配，这对于不可变列表或仅限于单个线程（如UI线程仅使用）的用法很有用。
 * 但是，此方法将不会检测到并发修改，除非列表的大小会因此在迭代中更改，否则可能导致无法预测的行为。
 */
inline fun <T> List<T>.forEachWithIndex(action: (Int, T) -> Unit) {
    val initialSize = size
    for (i in 0..lastIndex) {
        if (size != initialSize) throw ConcurrentModificationException()
        action(i, get(i))
    }
}

/**
 * 使用索引而不是像forEach那样的Iterator迭代接收方List ，但顺序相反（从最后一个索引降到零）。
 * 使用此功能可保存Iterator分配，这对于不可变列表或仅限于单个线程（如UI线程仅使用）的用法很有用。
 * 但是，此方法将不会检测到并发修改，除非列表的大小会因此在迭代中更改，否则可能导致无法预测的行为。
 */
inline fun <T> List<T>.forEachReversedByIndex(action: (T) -> Unit) {
    val initialSize = size
    for (i in lastIndex downTo 0) {
        if (size != initialSize) throw ConcurrentModificationException()
        action(get(i))
    }
}

/**
 * 使用索引而不是像forEach那样的Iterator迭代接收方List ，但顺序相反（从最后一个索引降到零）。
 * 使用此功能可保存Iterator分配，这对于不可变列表或仅限于单个线程（如UI线程仅使用）的用法很有用。
 * 但是，此方法将不会检测到并发修改，除非列表的大小会因此在迭代中更改，否则可能导致无法预测的行为。
 */
inline fun <T> List<T>.forEachReversedWithIndex(action: (Int, T) -> Unit) {
    val initialSize = size
    for (i in lastIndex downTo 0) {
        if (size != initialSize) throw ConcurrentModificationException()
        action(i, get(i))
    }
}
